﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

using SpectrEngine.Framework;
using SpectrEngine.Framework.Input;

using CellWarzGame.Screens;

namespace CellWarzGame.Actors
{
    public class TestActor
        : DrawableGameNode
    {
        const float MinForce = 0.0001f;
        const float MoveForce = 0.005f;
        const float TorqueForce = 0.005f;

        private Texture2D spriteSheet;
        private float speed = 80.0f;

        protected float angularDamping;
        public float AngularDamping
        {
            get
            {
                return angularDamping;
            }
            set
            {
                angularDamping = value;
            }
        }

        protected float linearDamping;
        public float LinearDamping
        {
            get
            {
                return linearDamping;
            }
            set
            {
                linearDamping = value;
            }
        }

        protected Vector2 directionalForce;
        public Vector2 DirectionalForce
        {
            get
            {
                return directionalForce;
            }
            set
            {
                directionalForce = value;
            }
        }

        protected float torque;
        public float Torque
        {
            get
            {
                return torque;
            }
            set
            {
                torque = value;
            }
        }

        public TestActor(Game game)
            : base(game, new Vector2(400.0f, 300.0f), 0.0f, Vector2.One)
        {
            game.Services.GetService<IPlayScreenService>().Register(this);
            spriteSheet = Game.Content.Load<Texture2D>("Test\\test_ship");
            LinearDamping = 0.001f;
            AngularDamping = 0.005f;
            directionalForce = new Vector2(0, 0);
            torque = 0;
        }

        public override void Update(GameTime gameTime)
        {
            Vector2 v = GamePadManager.GetThumbstick(PlayerIndex.One, GamePadThumbSticks.Left);

            //Translate(v * (float)gameTime.ElapsedGameTime.TotalSeconds * speed);
            if (v.Y != 0)
            {
                ApplyForce(new Vector2(0, v.Y), MoveForce);
            }
            if (v.X != 0)
            {
                ApplyTorque(v.X * TorqueForce);
            }
            Move(gameTime.ElapsedGameTime.Milliseconds);
        }

        public override void Draw(GameTime gameTime, Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(spriteSheet, position, null, Color.White, rotation, new Vector2(spriteSheet.Width / 2, spriteSheet.Height / 2), size, SpriteEffects.None, 0);
        }

        public void ApplyForce(Vector2 dir, float force)
        {
            //dir *= force;
            float a1 = (float)Math.Atan2(directionalForce.Y, directionalForce.X);
            float a2 = (float)Math.Atan2(dir.Y, dir.X);

            //float temp = (float)Math.Cos(a2);
            directionalForce.X = directionalForce.X + force * (float)Math.Cos(a2);
            directionalForce.Y = directionalForce.Y + force * (float)Math.Sin(a2);
        }

        public void ApplyTorque(float torque)
        {
            this.torque += torque;
        }

        private void Move(float time)
        {
            float x = 0;
            float y = 0;

            if (Math.Abs(torque) > MinForce)
            {
                Rotate( torque );
                torque -= torque * angularDamping * time;
            }
            else
            {
                torque = 0;
            }

            if (Math.Abs(directionalForce.X) > MinForce)
            {
                x = directionalForce.X * time;
                directionalForce.X -= directionalForce.X * linearDamping * time;
            }
            else
            {
                directionalForce.X = 0;
            }

            if (Math.Abs(directionalForce.Y) > MinForce)
            {
                y = directionalForce.Y * time;
                directionalForce.Y -= directionalForce.Y * linearDamping * time;
            }
            else
            {
                directionalForce.Y = 0;
            }
            
            if ( x != 0 || y != 0 )
            {
                Translate(Position-Vector2.Transform(new Vector2(x, y), World));
            }
        }
    }
}
